/*
 * Copyright (c) 2009 Roman Savelyev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "terminalproxy.h"
#include "conuisurfacelogger.h"
#include <ecom.h>

const TInt KTerminalFailureError = KErrNotReady;

CTerminalFailure::CTerminalFailure(MConUiTerminalObserver& aObserver) :
    iObserver(aObserver)
    {}

TSize CTerminalFailure::SurfaceSize()
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    return TSize(KErrNotFound, KErrNotFound);
    }

void CTerminalFailure::SetBackground(ConUiDef::TColor /*aColor*/)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::SetForeground(ConUiDef::TColor /*aColor*/)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::SetBold(TBool /*aBold*/)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::SetInverseVideo(TBool aInverseVideo)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::SetPos(const TPoint& /*aPoint*/)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::HideCursor()
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::ShowCursor()
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::Write(const TDesC& /*aOutput*/)
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::ClearSurface()
    {
    iObserver.HandleTerminalError(KTerminalFailureError);
    }

void CTerminalFailure::ReadKey(TConsoleKey& /*aKey*/, TRequestStatus& aStatus)
    {
    TRequestStatus* status = &aStatus;
    User::RequestComplete(status, KTerminalFailureError);
    }

void CTerminalFailure::ReadKeyCancel()
    {
    }
///////////////////////////////////////////////////////////////////////////////
CTerminalProxy* CTerminalProxy::NewL(const TDesC8& aTerminalType, MConUiTerminalObserver& aObserver)
    {
    FL(_L("CTerminalProxy::NewL"));
    CTerminalProxy* self = new(ELeave) CTerminalProxy(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL(aTerminalType);
    CleanupStack::Pop(self);
    return self;
    }

CTerminalProxy::CTerminalProxy(MConUiTerminalObserver& aObserver) :
    iObserver(aObserver),
    iTerminal(NULL)
    {}

void CTerminalProxy::ConstructL(const TDesC8& aTerminalType)
    {
    FL(_L("CTerminalProxy::ConstructL"));
    iTerminal = CConUiTerminal::NewL(aTerminalType, *this);
    }

CTerminalProxy::~CTerminalProxy()
    {
    FL(_L("CTerminalProxy::~CTerminalProxy"));
    Destroy();
    }

TSize CTerminalProxy::SurfaceSize()
    {
    return iTerminal->SurfaceSize();
    }

void CTerminalProxy::SetBackground(ConUiDef::TColor aColor)
    {
    iTerminal->SetBackground(aColor);
    }

void CTerminalProxy::SetForeground(ConUiDef::TColor aColor)
    {
    iTerminal->SetForeground(aColor);
    }

void CTerminalProxy::SetBold(TBool aBold)
    {
    iTerminal->SetBold(aBold);
    }

void CTerminalProxy::SetInverseVideo(TBool aInverseVideo)
    {
    iTerminal->SetInverseVideo(aInverseVideo);
    }

void CTerminalProxy::SetPos(const TPoint& aPoint)
    {
    iTerminal->SetPos(aPoint);
    }

void CTerminalProxy::HideCursor()
    {
    iTerminal->HideCursor();
    }

void CTerminalProxy::ShowCursor()
    {
    iTerminal->ShowCursor();
    }

void CTerminalProxy::Write(const TDesC& aOutput)
    {
    iTerminal->Write(aOutput);
    }

void CTerminalProxy::ClearSurface()
    {
    iTerminal->ClearSurface();
    }

void CTerminalProxy::ReadKey(TConsoleKey& aKey, TRequestStatus& aStatus)
    {
    iTerminal->ReadKey(aKey, aStatus);
    }

void CTerminalProxy::ReadKeyCancel()
    {
    iTerminal->ReadKeyCancel();
    }

void CTerminalProxy::HandleTerminalError(TInt aError)
    {
    FL(_L("CTerminalProxy::HandleTerminalError"));
    FLTRACEVALUE(aError);
    Destroy();
    // in order to change the behavior of the object
    // we switch VTBL
    new(this) CTerminalFailure(iObserver);
    }

void CTerminalProxy::Destroy()
    {
    FL(_L("CTerminalProxy::Destroy"));
    if (iTerminal)
        {
        delete iTerminal;
        REComSession::FinalClose();
        }
    }
///////////////////////////////////////////////////////////////////////////////
